package cn.codergege.demo.service

import cn.codergege.demo.dao.primary.PrimaryPersonRepository
import cn.codergege.demo.dao.secondary.SecondaryPersonRepository
import cn.codergege.demo.entity.primary.Person
import cn.codergege.demo.entity.secondary.Person as PersonSecondary
import cn.codergege.demo.entity.primary.QPerson.person
import com.querydsl.core.types.Predicate
import org.springframework.beans.BeanUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cache.annotation.CacheConfig
import org.springframework.cache.annotation.CacheEvict
import org.springframework.cache.annotation.CachePut
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Service

@CacheConfig(cacheNames = arrayOf("person"))
@Service
class PersonService {
   @Autowired
   lateinit var primaryPersonRepository: PrimaryPersonRepository

   @Autowired
   lateinit var secondaryPersonRepository: SecondaryPersonRepository

    /**
     *  从 primary 查询一个 person, 插入 secondary
     */
   fun multiDsService() {
      val person = primaryPersonRepository.findById(1).get();
        var personSecondary = PersonSecondary()
       println(person)
        if(person.description == null) {
            person.description = "默认描述"
        }

       BeanUtils.copyProperties(person, personSecondary, "id", "createTime")
       println(personSecondary)
       // 写入 secondary
       secondaryPersonRepository.saveAndFlush(personSecondary)
    }

    /**
    * 缓存:
    *    1. @Cacheable 常用于查询
    *       默认 key :
    *          1) 没有参数, key = new SimpleKey();
    *          2) 1 个参数, key 等于这个参数
    *          3) 多个参数, key = new SimpleKey(多个参数)
    *    2. @CachePut 常用于更新, 将更新后的返回值缓存起来(同步更新缓存)
    *       使用 @CachePut(value = "person", key = "#result.id")
    *    3. @CacheEvict 常用于删除, 将删除的结果从缓存中删除
    */

   //   @Cacheable("person")
   @Cacheable
   fun findPersonById(id: Int): Person {
      println("查询 id 是 $id 的 person.")
      return primaryPersonRepository.findById(id).get()
   }
   @CachePut(value = "person", key = "#result.id")
   fun updatePerson(person: Person): Person {
      return primaryPersonRepository.saveAndFlush(person)
   }
   @CacheEvict(value = "person", key = "#id")
   fun deletePerson(id: Int) {
      primaryPersonRepository.deleteById(id)
   }

   @Cacheable(value = "person")
   fun findPersons(name: String): List<Person>? {
      return primaryPersonRepository.findByName(name)
   }

   fun findPersonsByGender(gender: Int): Iterable<Person>? {
      val predicate: Predicate = person.gender.eq(gender)
      return primaryPersonRepository.findAll(predicate)
   }
}
